package com.caishi.lkx.exam.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.caishi.lkx.common.AdminBaseApi;
import com.caishi.lkx.common.role.Roles;
import com.caishi.lkx.exam.model.*;
import com.caishi.lkx.exam.service.*;

import com.zzw.common.Wrappers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;


@Tag(name = "套餐管理")
@Slf4j
@RestController
@RequestMapping("/exam/package/sku")
public class PackageSkuApi extends AdminBaseApi<IPackageSkuService, PackageSkuModel, String> {
    @Resource
    private IPackageSkuService packageSkuService;
    @Resource
    private IPackageService packageService;
    @Resource
    private IExamService examService;

    @Resource
    private IIndustryService industryService;
    @Resource
    private IPackageSkuAttrService packageSkuAttrService;
    @Resource
    private ICategoryService categoryService;
    @Resource
    private IColumnService columnService;
    @Resource
    private IProductBaseService productBaseService;

    @Override
    public IPackageSkuService loadService() {
        return packageSkuService;
    }

    @Override
    protected LambdaQueryWrapper<PackageSkuModel> baseWrapper(PackageSkuModel model, JSONObject otherParam) {
        List<String> skuAttrIds = model.getSkuAttrIds();
        List<Long> categoryIds = model.getCategoryIds();
        model.setSkuAttrIds(null);
        model.setCategoryIds(null);
        String join = null;
        if (null != categoryIds && !categoryIds.isEmpty()) {
            join = StringUtils.join(categoryIds,",");
        }
        LambdaQueryWrapper<PackageSkuModel> wrapper =
                super.baseWrapper(
                                model.clearEmptyStringField("name", "skuAttrIds", "categoryIds"), otherParam)
                        .like(StrUtil.isNotBlank(model.getName()), PackageSkuModel::getName, model.getName())
                        .apply(StrUtil.isNotBlank(join), "JSON_CONTAINS(category_ids, JSON_ARRAY(" + join + "))");
        if (CollUtil.isNotEmpty(skuAttrIds)) {
            wrapper.apply(getMysqlJsonContainsSql(skuAttrIds));
        }
        if (ExamModel.ZY.equals(model.getExamType()) && StrUtil.isBlank(model.getIndustryId())) {
            wrapper.ne(PackageSkuModel::getIndustryId, ExamModel.GJTK);
        }
        return wrapper;
    }

    public String getMysqlJsonContainsSql(List<String> ids) {
        StringBuilder builder = new StringBuilder();
        ids.forEach(id -> builder.append("'").append(id).append("',"));
        String str = builder.toString();
        str = str.substring(0, str.length() - 1);
        return "JSON_CONTAINS(sku_attr_ids, JSON_ARRAY(" + str + "))";

    }
    @Operation(summary = "根据套餐查询套餐sku")
    @Parameters({
            @Parameter(name = "packageId", description = "套餐Id"),
    })
    @Override
    @GetMapping("/list")
    public List<PackageSkuModel> list(@RequestParam(defaultValue = "1000") Integer size, @ModelAttribute PackageSkuModel model, @NotNull JSONObject otherParam) {
        if (size > 10000) {
            size = 10000;
        }
        return listCover(loadService().selectList(loadService().wrapperProcessing(baseWrapper(model, otherParam).last(" limit " + size))), otherParam);
    }

    public static void main(String[] args) throws ClassNotFoundException {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        StringBuilder builder = new StringBuilder();
        StringJoiner joiner = new StringJoiner(",", "'", "'");
        list.forEach(l -> {
            builder.append("'").append(l).append("',");
            joiner.add(l);
        });
        String str = builder.toString();
        str = str.substring(0, str.length() - 1);
        System.err.println("JSON_CONTAINS(sku_attr_ids, JSON_ARRAY(" + str + "))");
        System.err.println(joiner);

        Class<?> aClass = Class.forName("com.vip.langrun.exam.api.PackageSkuApi");
        System.err.println(aClass.getName());
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.err.println(declaredMethod.getReturnType());
            System.err.println(declaredMethod.getGenericReturnType());
        }

    }

    @Override
    protected List<PackageSkuModel> listCover(List<PackageSkuModel> result, JSONObject otherParam) {
        result = result.parallelStream().peek(r -> {
            if (otherParam.getBool("base", false)) {
                if (StrUtil.isNotBlank(r.getIndustryId())) {
                    r.setIndustryName(industryService.queryName(r.getIndustryId()));
                }
                if (StrUtil.isNotBlank(r.getExamId())) {
                    r.setExamName(examService.queryName(r.getExamId()));
                }
                if (StrUtil.isNotBlank(r.getPackageId())) {
                    r.setPackageName(packageService.queryName(r.getPackageId()));
                }

                if (CollUtil.isNotEmpty(r.getSkuAttrIds())) {
                    r.setSkuAttrNameList(packageSkuAttrService.getNameListByIds(r.getSkuAttrIds()));
                }
                if (CollUtil.isNotEmpty(r.getCategoryIds())) {
                    r.setCategoryNameList(categoryService.getNameListByIds(r.getCategoryIds()));
                }
            }
            if (otherParam.getBool("attr", false)) {
                r.setSkuAttrNameList(packageSkuAttrService.getNameListByIds(r.getSkuAttrIds()));
            }

        }).collect(Collectors.toList());

        return result;
    }

    @PutMapping("/changeStatus")
    public PackageSkuModel changeStatus(@RequestParam String id, @RequestParam Boolean enable) {
        PackageSkuModel model = new PackageSkuModel();
        model.setId(id);
        model.setEnable(enable);
        return super.update(model);
    }

    //======================pc端数据查询============================
    @GetMapping("/getSku")
    @Operation(summary = "pc通过套餐id , sku属性ids, 科目id,栏目id 获取第一个满足条件的sku ")
    @Parameters({
            @Parameter(name = "packageId", description = "套餐id"),
            @Parameter(name = "skuAttrIds", description = "sku属性Ids"),
            @Parameter(name = "categoryId", description = "科目id"),
            @Parameter(name = "columnId", description = "栏目id"),
    })
    @Roles
    public PackageSkuModel getPackage(@RequestParam String packageId, @RequestParam(required = false) Long categoryId, @RequestParam(required = false) List<String> skuAttrIds, @RequestParam(required = false) String columnId) {
        //产品id  通过栏目id 反查
        List<String> productIds = null;
        if (StrUtil.isNotBlank(columnId)) {
            ColumnModel column = columnService.getById(columnId);
            if (null == column) {
                return null;
            }
            List<ProductBaseModel> productBaseModels = productBaseService.selectListByColumnId(column.getCategoryId(), columnId);
            if (CollUtil.isEmpty(productBaseModels)) {
                return null;
            }
            productIds = productBaseModels.stream().map(ProductBaseModel::getId).collect(Collectors.toList());
        }
        String sql = null;
        if (CollUtil.isNotEmpty(skuAttrIds)) {
            sql = this.getMysqlJsonContainsSql(skuAttrIds);
        }
        List<PackageSkuModel> packageSkuModels = packageSkuService.selectList(Wrappers.<PackageSkuModel>lambdaQuery().eq(PackageSkuModel::getPackageId, packageId).eq(PackageSkuModel::getEnable, true)
                .apply(null != categoryId, "JSON_CONTAINS(category_ids, CONCAT(" + categoryId + "))").apply(CollUtil.isNotEmpty(skuAttrIds), sql));
        if (CollUtil.isNotEmpty(packageSkuModels) && CollUtil.isNotEmpty(productIds)) {
            List<String> finalProductIds = productIds;
            packageSkuModels = packageSkuModels.stream().filter(p -> CollUtil.isNotEmpty(p.getProductIds()) && this.listRetain(p.getProductIds(), finalProductIds)).collect(Collectors.toList());
        }
        if (CollUtil.isNotEmpty(packageSkuModels)) {
            return packageSkuModels.stream().peek(s -> {
                s.setPrice(BigDecimal.valueOf(s.getPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).longValue());
                s.setTmPrice(BigDecimal.valueOf(s.getTmPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).longValue());
                s.setAgentPrice(BigDecimal.valueOf(s.getAgentPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).longValue());
            }).sorted(Comparator.comparing(PackageSkuModel::getSort)).toList().get(0);
        }
        return null;
    }

    private Boolean listRetain(List<String> l1, List<String> l2) {
        l1.retainAll(l2);
        return CollUtil.isNotEmpty(l1);

    }

    @GetMapping("/package-guige-category")
    @Roles
    public List<PackageSkuAttrModel> getCategory(@RequestParam String packageId, @RequestParam("skuAttrIds") List<String> skuAttrIds) {
        List<PackageSkuModel> packageSkuModels = packageSkuService.selectList(Wrappers.<PackageSkuModel>lambdaQuery().eq(PackageSkuModel::getPackageId, packageId).apply(getMysqlJsonContainsSql(skuAttrIds)));
        List<String> attrIds = packageSkuModels.parallelStream().flatMap(m -> m.getSkuAttrIds().stream()).distinct().filter(f -> !(f.equals("danke") || f.equals("quanke"))).toList();
        List<PackageSkuAttrModel> skuAttrModels = new ArrayList<>();
        if (!attrIds.isEmpty()) {
            skuAttrModels = packageSkuAttrService.selectBatchIds(attrIds);
        }
        return skuAttrModels;
    }


}
